﻿using System;
using System.Collections.Generic;
using System.Text;
using Microsoft.Win32;
using PCDoctor.ScanParameters;
using System.ServiceProcess;

namespace PCDoctor.Utils
{
    class Restorer
    {
        /// <summary>
        /// Событие "восстановлена очередная настройка"
        /// </summary>
        public event RestoreProgress RestoreProgressed;

        protected virtual void OnRestoreProgressed(RestoreProgressEventArgs e)
        {
            RestoreProgressed(this, e);
        }

        protected RegistryKey getKeyByPath(string path)
        {
            RegistryKey currentKey = null;
            //Расчленяем строку пути для получения раздела и ключа реестра
            string[] pathParts = path.Split('\\');
            switch (pathParts[0].ToUpper())
            {
                case "HKEY_LOCAL_MACHINE":
                    currentKey = Registry.LocalMachine;
                    break;
                case "HKEY_CURRENT_USER":
                    currentKey = Registry.CurrentUser;
                    break;
                case "HKEY_CLASSES_ROOT":
                    currentKey = Registry.ClassesRoot;
                    break;
            }
            return currentKey;
        }

        protected string getValuePathByPath(string path)
        {
            string[] pathParts = path.Split('\\');
            return path.Replace(pathParts[0] + "\\", "").
                Replace("\\" + pathParts[pathParts.Length - 1], "");
        }

        protected string getValueNameByPath(string path)
        {
            string[] pathParts = path.Split('\\');
            return pathParts[pathParts.Length - 1];
        }

        protected void setRegistryValue(string path, string value)
        {
            RegistryKey key = getKeyByPath(path);
            string valueName = getValueNameByPath(path);
            string valuePath = getValuePathByPath(path);
            try
            {
                RegistryKey rk = key.OpenSubKey(valuePath, true);
                if (rk != null)
                {
                    if (value == "___not_exists" && valueName != "Enable")
                    {
                        rk.DeleteValue(valueName);
                    }
                    else
                    {
                        rk.SetValue(valueName, value);
                    }
                }
            }
            catch (Exception e)
            {
                ErrorHandler.HandleError(e.Message);
            }
        }

        protected void setRegistryValue(string path, object value, RegistryValueKind kind)
        {
            RegistryKey key = getKeyByPath(path);
            string valueName = getValueNameByPath(path);
            string valuePath = getValuePathByPath(path);
            try
            {
                RegistryKey rk = key.OpenSubKey(valuePath, true);
                if (rk != null)
                {
                    if (Convert.ToString(value) == "___not_exists")
                    {
                        rk.DeleteValue(valueName);
                    }
                    else
                    {
                        rk.SetValue(valueName, value, kind);
                    }
                }
            }
            catch (Exception e)
            {
                ErrorHandler.HandleError(e.Message);
            }
        }

        public void RestoreProblem(int problemId)
        {
            try
            {
                RegistryKey key = Registry.LocalMachine.OpenSubKey(
                    "Software\\Hauberk Software\\PCDoctorBackup");
                if (key != null)
                {
                    string[] subKeyNames = key.GetSubKeyNames();
                    foreach (string subKeyName in subKeyNames)
                    {
                        if (subKeyName.Contains("problem_" + problemId.ToString()))
                        {
                            RegistryKey paramKey = key.OpenSubKey(subKeyName);
                            if (paramKey != null)
                            {
                                string value = Convert.ToString(paramKey.GetValue("value"));
                                string path = Convert.ToString(paramKey.GetValue("path"));
                                setRegistryValue(path, value);
                            }
                        }
                    }
                }

            }
            catch (Exception e)
            {
                ErrorHandler.HandleError(e.Message);
            }
        }

        public void RestoreAll()
        {
            try
            {
                RegistryKey key = Registry.LocalMachine.OpenSubKey(
                    "Software\\Hauberk Software\\PCDoctorBackup");
                if (key != null)
                {
                    string[] subKeyNames = key.GetSubKeyNames();
                    int i = 0;
                    foreach (string subKeyName in subKeyNames)
                    {
                        i++;
                        RegistryKey paramKey = key.OpenSubKey(subKeyName, false);
                        if (paramKey != null)
                        {
                            Int64 kind = Convert.ToInt64(paramKey.GetValue("FixerKind"));
                            if (kind == (Int64)ScanFixerKinds.Registy)
                            {
                                setRegistryValue(
                                    Convert.ToString(paramKey.GetValue("path")),
                                    Convert.ToString(paramKey.GetValue("value"))
                                );
                            }
                            else
                            {
                                string serviceName = Convert.ToString(paramKey.GetValue("path"));
                                string[] parts = Convert.ToString(paramKey.GetValue("value")).Split('+');
                                setRegistryValue(
                                    @"HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\" +
                                        serviceName + @"\Start",
                                    int.Parse(parts[0]), RegistryValueKind.DWord
                                );
                                if (parts[1] == "running")
                                {
                                    try
                                    {
                                        ServiceController sc = new ServiceController(serviceName);
                                        sc.Start();
                                    }
                                    catch (Exception e)
                                    {
                                        ErrorHandler.HandleError(e.Message);
                                    }
                                }
                            }
                        }
                        OnRestoreProgressed(new RestoreProgressEventArgs
                        {
                            Progress = (float)Math.Round(((double)i / subKeyNames.Length * 100), 1),
                            RestoresCount = subKeyNames.Length
                        });
                        paramKey.Close();
                    }
                }

            }
            catch (Exception e)
            {
                ErrorHandler.HandleError(e.Message);
            }
        }
    }

    /// <summary>
    /// Класс аргументов события "Просканирована очередная проблема"
    /// </summary>
    public class RestoreProgressEventArgs : EventArgs
    {
        public float Progress { get; set; }
        public int RestoresCount { get; set; }
    }

    public delegate void RestoreProgress(object sender, RestoreProgressEventArgs e);
}
